﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WHControlLib.Controls.Chart
{
    public partial class WHbaseScaleChart : UserControl
    {
        public WHbaseScaleChart()
        {//设置双缓冲开启禁止背景擦拭
            SetStyle(
                     ControlStyles.OptimizedDoubleBuffer
                     | ControlStyles.ResizeRedraw
                     | ControlStyles.Selectable
                     | ControlStyles.AllPaintingInWmPaint
                     | ControlStyles.UserPaint
                     | ControlStyles.SupportsTransparentBackColor,
                     true);

            InitializeComponent();
        }
        //***********全局参数定义***********************
         public Rectangle RulerRect = new Rectangle();
        Rectangle MyRect = new Rectangle();
        public class UserValue
        {
            private float _x;

            public float X
            {
                get { return _x; }
                set
                {
                    if (value > 0 && value <= 1)

                        _x = value;
                    else
                    {
                        if (value < 0)

                            _x = 0;

                        if (value > 1)

                            _x = 1;


                    }

                }
            }

            private float _y;

            public float Y
            {
                get { return _y; }
                set
                {
                    if (value > 0 && value <= 1)

                        _y = value;
                    else
                    {
                        if (value < 0)

                            _y = 0;

                        if (value > 1)

                            _y = 1;


                    }
                }
            }
            public string UserValueMsg { get; set; }

        }
        public List<UserValue> UserValues = new List<UserValue>();

        public List<PointF> UserPoints = new List<PointF>();
        //********************************************

        #region 属性定义

        private int _rulerBodyBlank =35;
        [Category("A我的刻度"), Description(" 尺体距离控件边缘的空白距离，默认，35像素"), Browsable(true)]
        public int RulerBodyBlank
        {
            get { return _rulerBodyBlank; }
            set
            {
                _rulerBodyBlank = value;

                this.Invalidate();
            }
        }

        private int _rulerHorScaleNum = 6;
        [Category("A我的刻度"), Description(" 水平方向有几个刻度，默认，6 个"), Browsable(true)]
        public int RulerHorScaleNum
        {
            get { return _rulerHorScaleNum; }
            set
            {
                if (value > 0)
                {
                    _rulerHorScaleNum = value;
                }
                else _rulerHorScaleNum = 1;

                this.Invalidate();
            }
        }

        private int _rulerVerScaleNum = 6;
        [Category("A我的刻度"), Description(" 竖向方向有几个刻度，默认，6 个"), Browsable(true)]
        public int RulerVerScaleNum
        {
            get { return _rulerVerScaleNum; }
            set
            {
                if (value > 0)
                {
                    _rulerVerScaleNum = value;
                }
                else _rulerVerScaleNum = 1;

                this.Invalidate();
            }
        }

        private bool _isShowRulerScale = true;
        [Category("A我的刻度"), Description(" 是否显示刻度，默认，显示"), Browsable(true)]
        public bool IsShowRulerScale
        {
            get { return  _isShowRulerScale; }
            set
            {
                _isShowRulerScale = value;



                this.Invalidate();
            }
        }
        private int _rulerScaleHeight = 7;
        [Category("A我的刻度"), Description(" 刻度标的长度，默认，7 个像素"), Browsable(true)]
        public int RulerScaleHeight
        {
            get { return _rulerScaleHeight; }
            set
            {
                if (value > 0)
                {
                    _rulerScaleHeight = value;
                }
                else
                    _rulerScaleHeight = 5;

                this.Invalidate();
            }
        }
 
      

        private float _rulerBodyWidth = 2.0f;
        [Category("A我的刻度"), Description(" 尺体线宽，默认，2.0f"), Browsable(true)]
        public float RulerBodyWidth
        {
            get { return _rulerBodyWidth; }
            set
            {
                if (value > 0)
                {
                    _rulerBodyWidth = value;
                }
                else _rulerBodyWidth = 1;


                this.Invalidate();
            }
        }
        private float _rulerScaleWidth = 2.0f;
        [Category("A我的刻度"), Description(" 尺体刻度线宽，默认，2.0f"), Browsable(true)]
        public float RulerScaleWidth
        {
            get { return _rulerScaleWidth; }
            set
            {
                if (value > 0)
                {
                    _rulerScaleWidth = value;
                } else
                _rulerScaleWidth = 1;

                this.Invalidate();
            }
        }

        private int _labelToRulerWidth = 8;
        [Category("A我的刻度"), Description(" 标签与尺体之间的距离，默认，8个像素"), Browsable(true)]
        public int LabelToRulerWidth
        {
            get { return _labelToRulerWidth; }
            set
            {
                if (value > 0)
                {
                    _labelToRulerWidth = value;
                }
                else
                    _labelToRulerWidth = 1;

                this.Invalidate();
            }
        }

        private Color _rulerLineColor = Color.Black;
        [Category("A我的刻度"), Description(" 尺线的颜色，默认，黑色"), Browsable(true)]
        public Color RulerLineColor
        {
            get { return _rulerLineColor; }
            set
            {
                _rulerLineColor = value;

                this.Invalidate();
            }
        }


        private Color _scaleLabelTextColor = Color.Black;
        [Category("A我的刻度"), Description(" 刻度标签文本的颜色，默认，黑色"), Browsable(true)]
        public Color ScaleLabelTextColor
        {
            get { return _scaleLabelTextColor; }
            set
            {
                _scaleLabelTextColor = value;

                this.Invalidate();
            }
        }


        private Color _rulerScaleColor = Color.Black;
        [Category("A我的刻度"), Description(" 尺子刻度线的颜色，默认，黑色"), Browsable(true)]
        public Color RulerScaleColor
        {
            get { return _rulerScaleColor; }
            set
            {
                _rulerScaleColor = value;

                this.Invalidate();
            }
        }

        private Font _rulerScaleLabelFont = new Font("微软雅黑", 8.0f);
        [Category("A我的刻度"), Description(" 尺子刻度线标签的字体，默认，微软雅黑"), Browsable(true)]
        public Font RulerScaleLabelFont
        {
            get { return _rulerScaleLabelFont; }
            set
            {
                _rulerScaleLabelFont = value;

                this.Invalidate();
            }
        }
        //******************用户坐标点样式设置***************

        private Font _userValueMsgFont = new Font("微软雅黑", 8.0f);
        [Category("A我的刻度"), Description(" 用户坐标点信息显示的字体，默认，微软雅黑"), Browsable(true)]
        public Font UserValueMsgFont
        {
            get { return _userValueMsgFont; }
            set
            {
                _userValueMsgFont = value;

                this.Invalidate();
            }
        }

        private Color _userValueMsgColor= Color.Black;
        [Category("A我的刻度"), Description(" 用户坐标点信息显示的颜色，默认，黑色"), Browsable(true)]
        public Color UserValueMsgColor
        {
            get { return _userValueMsgColor ; }
            set
            {
                _userValueMsgColor = value;

                this.Invalidate();
            }
        }
        private bool _isShowUserValueMsg=true;
        [Category("A我的刻度"), Description(" 是否显示用户坐标点信息，默认：true"), Browsable(true)]
        public bool IsShowUserValueMsg
        {
            get { return _isShowUserValueMsg; }
            set { _isShowUserValueMsg = value; this.Invalidate(); }
        }

        //******************用户坐标点样式设置结束***************

        //刻度的标签文本集合
        private List<string> _horScaleLabelList = new List<string>();
        //private List<string> _horScaleLabelList ;
        [Category("A我的刻度"), Description(" 水平刻度标签集合，默认，无"), Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")]
        public List<string> HorScaleLabelList
        {
            get { return _horScaleLabelList; }
            set
            {
                if (_horScaleLabelList == null)
                {
                    _horScaleLabelList = new List<string>();
                }
                else
                _horScaleLabelList = value;
                this.Invalidate();
            }
        }

        //垂直刻度的标签文本集合
        private List<string> _verScaleLabelList = new List<string>();

        [Category("A我的刻度"), Description(" 垂直刻度标签集合，默认，无"), Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")]
        public List<string> VerScaleLabelList
        {
            get { return _verScaleLabelList; }
            set
            {
                if (_verScaleLabelList == null)
                {
                    _verScaleLabelList = new List<string>();
                }
                else
                    _verScaleLabelList = value;
                this.Invalidate();
            }
        }


        #endregion

        public void BeforePaint()
        {
            MyRect = this.ClientRectangle;
           RulerRect= GetRulerRect(MyRect,RulerBodyBlank);

      UserValuesToPoint(RulerRect, UserValues);
        }
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            BeforePaint();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics Myg = e.Graphics;

           
           

            DrawHorRulerBody(Myg, RulerRect);
            DrawVerRulerBody(Myg, RulerRect);




        }
        //******************刻度功能实现***********************
 
       public Rectangle GetRulerRect(Rectangle MyRect,int RulerBodyBlank)
        {
            Rectangle rulerRect = new Rectangle();
            rulerRect.X = MyRect.X + RulerBodyBlank;
            rulerRect.Y = MyRect.Y + RulerBodyBlank;
            rulerRect.Height = MyRect.Height - (RulerBodyBlank * 2)+(int)RulerBodyWidth;
            rulerRect.Width = MyRect.Width - (RulerBodyBlank * 2)+ (int)RulerBodyWidth;
            return rulerRect;
        }

      public  void DrawHorRulerBody(Graphics Myg, Rectangle RulerRect)
        {
            using (SolidBrush horRulerBodyBrush = new SolidBrush(RulerLineColor))
            {
                using (Pen horRulerPen = new Pen(horRulerBodyBrush, RulerBodyWidth))
                {
                    Point startPoint = new Point();
                    startPoint.X = RulerRect.Left;
                    startPoint.Y = RulerRect.Bottom - (int)RulerBodyWidth / 2;
                    Point endPoint = new Point();
                    endPoint.X = RulerRect.Right;
                    endPoint.Y = RulerRect.Bottom - (int)RulerBodyWidth / 2;
                    Myg.DrawLine(horRulerPen, startPoint, endPoint);
                }
            }


            if (RulerHorScaleNum <= 0)
            {
                return;
            }
            //画水平刻度条



            int Scalewidth = (int)RulerRect.Width / RulerHorScaleNum;
            using (SolidBrush ScaleBrush = new SolidBrush(RulerScaleColor))
            {
                using (Pen ScalePen = new Pen(ScaleBrush, RulerScaleWidth))
                {
                    for (int i = 0; i < RulerHorScaleNum; i++)
                    {
                        int j = i + 1;
                        PointF scaleStartPoint = new PointF(RulerRect.Left + Scalewidth * j, RulerRect.Bottom);
                        PointF scaleEndPoint = new PointF(RulerRect.Left + Scalewidth * j, RulerRect.Bottom + RulerScaleHeight);
                        if (IsShowRulerScale)
                        {


                            Myg.DrawLine(ScalePen, scaleStartPoint, scaleEndPoint);
                        }
                        //显示水平刻度下标签文本
                        if (HorScaleLabelList.Count > 0 && i <= HorScaleLabelList.Count - 1)
                        {
                            using (SolidBrush sb = new SolidBrush(ScaleLabelTextColor))
                            {
                                string s = HorScaleLabelList[i].ToString();
                                SizeF labelSize = Myg.MeasureString(s, RulerScaleLabelFont);
                                PointF labelPoint = new PointF();
                                labelPoint.X = scaleStartPoint.X - labelSize.Width / 2;
                                labelPoint.Y = scaleStartPoint.Y + LabelToRulerWidth;
                                Myg.DrawString(s, RulerScaleLabelFont, sb, labelPoint);
                            }

                        }



                        /*

                            */
                    }

                }
            }
        }



   public    void DrawVerRulerBody(Graphics Myg, Rectangle RulerRect)
        {
            using (SolidBrush VerRulerBodyBrush = new SolidBrush(RulerLineColor))
            {
                using (Pen VerRulerPen = new Pen(VerRulerBodyBrush, RulerBodyWidth))
                {
                    Point startPoint = new Point();
                    startPoint.X = RulerRect.Left+(int) RulerBodyWidth/2;
                    startPoint.Y = RulerRect.Bottom;
                    Point endPoint = new Point();
                    endPoint.X = RulerRect.Left + (int)RulerBodyWidth / 2;
                    endPoint.Y = RulerRect.Top + (int)RulerBodyWidth / 2;

                    Myg.DrawLine(VerRulerPen, startPoint, endPoint);
                }


            }
            if (RulerVerScaleNum <= 0)
            {
                return;
            }


            int Scalewidth = (int)RulerRect.Height / RulerVerScaleNum;
            for (int i = 0; i < RulerVerScaleNum; i++)
            {
                int j = i + 1;
                Point scaleStartPoint = new Point(RulerRect.Left, (int)(RulerRect.Bottom - Scalewidth * j));
                Point scaleEndPoint = new Point(RulerRect.Left - RulerScaleHeight, (int)(RulerRect.Bottom - Scalewidth * j));
                if (IsShowRulerScale)
                {


                    using (SolidBrush ScaleBrush = new SolidBrush(RulerScaleColor))
                    {
                        using (Pen ScalePen = new Pen(ScaleBrush, RulerScaleWidth))
                        {

                            Myg.DrawLine(ScalePen, scaleStartPoint, scaleEndPoint);
                        }
                    }
                }

                //显示垂直刻度下标签文本
                if (VerScaleLabelList.Count > 0 && i <= VerScaleLabelList.Count - 1)
                {
                    using (SolidBrush sb = new SolidBrush(ScaleLabelTextColor))
                    {
                        string s = VerScaleLabelList[i].ToString();
                        SizeF labelSize = Myg.MeasureString(s, RulerScaleLabelFont);
                        PointF labelPoint = new PointF();
                        labelPoint.X = scaleStartPoint.X - labelSize.Width - LabelToRulerWidth;
                        labelPoint.Y = scaleStartPoint.Y - labelSize.Height / 2;
                        Myg.DrawString(s, RulerScaleLabelFont, sb, labelPoint);
                    }

                }

            }


        }
        /// <summary>
        /// 将用户的设置的坐标点转换为标尺范围内的具体点坐标
        /// </summary>
        /// <param name="rulerRect"></param>
        public void UserValuesToPoint(Rectangle rulerRect,List<UserValue> UserValues)
            
        {
            UserPoints.Clear();
            if (UserValues.Count > 0)
            {
                foreach (var item in UserValues)
                {
                    PointF p = new PointF(); 
                   //将用户坐标转变为比例尺矩形区域的坐标并扣除比例尺的作图线宽+RulerBodyWidth 
                    p.X = RulerRect.Left + rulerRect.Width * item.X/*+ RulerBodyWidth*/;
                    p.Y = RulerRect.Bottom - rulerRect.Height * item.Y/*- RulerBodyWidth*/;
                    UserPoints.Add(p);

                }
            }


        }


        /// <summary>
        /// 添加要显示的坐标点
        /// </summary>
        /// <param name="x">X轴方向相对于水平长度的比例</param>
        /// <param name="y">Y轴方向相对于垂直长度的比例</param>
        /// <param name="ValueMsg">坐标点的显示信息</param>
        public void AddUserValue(float x, float y,string ValueMsg)

        {
            UserValue UV = new UserValue();
            UV.X = x;
            UV.Y = y;
            UV.UserValueMsg = ValueMsg;
            UserValues.Add(UV);


        }
        /// <summary>
        ///  添加要显示的坐标点
        /// </summary>
        /// <param name="x">X轴方向相对于水平长度的比例</param>
        /// <param name="y">Y轴方向相对于垂直长度的比例</param>
        public void AddUserValue(float x, float y)

        {
            UserValue UV = new UserValue();
            UV.X = x;
            UV.Y = y;
        
            UserValues.Add(UV);


        }


        /// <summary>
        /// 清空所有用户要显示的坐标点
        /// </summary>
        public void ClearAllUserValues()
        {
            UserValues.Clear();
            UserPoints.Clear();
        }

        //*************##############################################################

    }
}
